{
 "cells": [
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-30T03:08:55.157862Z",
     "start_time": "2025-05-30T03:08:55.009638Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import numpy as np\n",
    "\n",
    "def euclidean_distance(point1, point2):\n",
    "    return np.sqrt(np.sum((point1 - point2) ** 2))\n",
    "\n",
    "def region_query(data, point_idx, eps):\n",
    "    neighbors = []\n",
    "    for idx, point in enumerate(data):\n",
    "        if euclidean_distance(data[point_idx], point) < eps:\n",
    "            neighbors.append(idx)\n",
    "    return neighbors\n",
    "\n",
    "def expand_cluster(data, labels, point_idx, neighbors, cluster_id, eps, min_samples):\n",
    "    labels[point_idx] = cluster_id\n",
    "    i = 0\n",
    "    while i < len(neighbors):\n",
    "        neighbor = neighbors[i]\n",
    "        if labels[neighbor] == -1:\n",
    "            labels[neighbor] = cluster_id\n",
    "        elif labels[neighbor] == 0:\n",
    "            labels[neighbor] = cluster_id\n",
    "            new_neighbors = region_query(data, neighbor, eps)\n",
    "            if len(new_neighbors) >= min_samples:\n",
    "                neighbors.extend(new_neighbors)\n",
    "        i += 1\n",
    "\n",
    "def dbscan(data, eps, min_samples):\n",
    "    labels = [0] * len(data)  # 0表示未处理，-1表示噪声，其他正数表示簇ID\n",
    "    cluster_id = 0\n",
    "    for point_idx in range(len(data)):\n",
    "        if labels[point_idx] != 0:\n",
    "            continue\n",
    "        neighbors = region_query(data, point_idx, eps)\n",
    "        if len(neighbors) < min_samples:\n",
    "            labels[point_idx] = -1  # 标记为噪声\n",
    "        else:\n",
    "            cluster_id += 1\n",
    "            expand_cluster(data, labels, point_idx, neighbors, cluster_id, eps, min_samples)\n",
    "    return labels\n",
    "\n",
    "# 生成模拟数据\n",
    "def generate_data():\n",
    "    # 这里只是一个简单的示例，实际数据可能更复杂\n",
    "    center1 = np.array([1, 1])\n",
    "    center2 = np.array([5, 5])\n",
    "    data1 = np.random.normal(loc=center1, scale=0.5, size=(100, 2))\n",
    "    data2 = np.random.normal(loc=center2, scale=0.5, size=(100, 2))\n",
    "    data = np.vstack((data1, data2))\n",
    "    return data\n",
    "\n",
    "# 主程序\n",
    "data = generate_data()\n",
    "eps = 0.8  # 邻域半径\n",
    "min_samples = 5  # 最小样本数\n",
    "labels = dbscan(data, eps, min_samples)\n",
    "\n",
    "# 打印结果\n",
    "print(\"Labels:\", labels)\n"
   ],
   "id": "90212f5311b48c0",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Labels: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]\n"
     ]
    }
   ],
   "execution_count": 6
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
